home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
SizeableExp.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-05
|
4KB
|
204 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "SizeableExp.h"
#include "Class.h"
#include "Command.h"
#include "Collection.h"
#include "Look.h"
#include "Math.h"
//---- SplitMover --------------------------------------------------------------
class SplitMover: public Command {
SplitArea *sap;
Direction dir;
Point min, max;
public:
SplitMover(SplitArea *sp, Direction d, Point mi, Point mx);
Command *TrackMouse(TrackPhase, Point, Point, Point);
void TrackConstrain(Point ap, Point pp, Point *np);
};
SplitMover::SplitMover(SplitArea *sp, Direction d, Point mi, Point mx)
{
sap= sp;
dir= d;
min= mi;
max= mx;
SetType(eCmdTypeNoChange);
}
Command *SplitMover::TrackMouse(TrackPhase tp, Point, Point pp, Point np)
{
Point d= np-pp;
switch (tp) {
case eTrackMove:
GrSetCursor(eCrsMoveHand);
sap->Control(sap->GetId(), cPartChangeSplit, &d);
break;
case eTrackRelease:
return gNoChanges;
default:
break;
}
return this;
}
void SplitMover::TrackConstrain(Point ap, Point, Point *np)
{
Point d= *np-ap;
if (dir == eVert)
np->y= ap.y+Math::Range(min.y, max.y, d.y);
else
np->x= ap.x+Math::Range(min.x, max.x, d.x);
}
//---- SplitArea --------------------------------------------------------------
SplitArea::SplitArea(int id, Direction d) : VObject(id)
{
dir= d;
if (dir == eVert)
SetFlag(eVObjVFixed);
else
SetFlag(eVObjHFixed);
}
GrCursor SplitArea::GetCursor(Point)
{
return (dir == eVert) ? eCrsUpDownArrow : eCrsLeftRightArrow;
}
Metric SplitArea::GetMinSize()
{
return gLook->SashLayout()->GetMinSize(this);
}
void SplitArea::Draw(Rectangle)
{
gLook->SashLayout()->Adorn(this, contentRect, 0);
}
Command *SplitArea::DoLeftButtonDownCommand(Point, Token, int)
{
Point min, max;
((SizeableExpander*)GetContainer())->GetStretchability(GetId(), min, max);
return new SplitMover(this, dir, min, max);
}
//---- SizeableExpander ---------------------------------------------------------
NewMetaImpl0(SizeableExpander, Expander);
SizeableExpander::SizeableExpander(int id, Direction d, Point, VObject *va_(vop), ...):
Expander(id, d, gPoint0, (SeqCollection*)0)
{
VObject *vp;
va_list ap;
va_start(ap,va_(vop));
Add(va_(vop));
for (int i= 0;; i++) {
if ((vp= va_arg(ap, VObject*)) == 0)
break;
Add(new SplitArea(i, d));
Add(vp);
}
va_end(ap);
}
void SizeableExpander::Control(int id, int part, void *val)
{
Point rc= ColsRowsSize();
Direction dir= (rc.x > rc.y) ? eHor : eVert;
if (part == cPartChangeSplit) {
Point dd;
dd[dir]= (*(Point*)val)[dir];
for (int i= 0; i < 3; i++) {
VObject *vop= At(id*2+i);
switch(i) {
case 0:
vop->SetExtent(vop->GetExtent()+dd);
break;
case 1:
vop->SetOrigin(vop->GetOrigin()+dd);
break;
case 2:
vop->SetOrigin(vop->GetOrigin()+dd);
vop->SetExtent(vop->GetExtent()-dd);
break;
}
vop->ForceRedraw();
}
}
}
void SizeableExpander::GetStretchability(int at, Point &min, Point &max)
{
VObject *vop= At(at*2);
min= vop->GetMinSize().Extent() - vop->GetExtent();
vop= At((at+1)*2);
max= vop->GetExtent() - vop->GetMinSize().Extent();
}
void SizeableExpander::SetExtent(Point e)
{
Iter next(MakeIterator());
register VObject *vop;
int d, div= 0, mod= 0, n= expandCnt();
Point newsize;
bool hfixed, vfixed;
Point rc= ColsRowsSize();
Direction dir= (rc.x > rc.y) ? eHor : eVert;
if (GetExtent() == gPoint0) // ????
d= (e-GetMinSize().extent)[dir];
else
d= (e - GetExtent())[dir];
VObject::SetExtent(e);
if (n > 0) {
div= d / n;
mod= d % n;
}
while (vop= (VObject*) next()) {
vfixed= vop->TestFlag(eVObjVFixed);
hfixed= vop->TestFlag(eVObjHFixed);
if (vop->GetExtent() == gPoint0) // ????
newsize= vop->GetMinSize().extent;
else
newsize= vop->GetExtent();
if (dir == eVert) {
if (!hfixed)
newsize.x= e.x;
if (!vfixed) {
newsize.y+= div;
if (mod > 0) {
newsize.y++;
mod--;
}
}
} else {
if (!vfixed)
newsize.y= e.y;
if (!hfixed) {
newsize.x+= div;
if (mod > 0) {
newsize.x++;
mod--;
}
}
}
vop->SetExtent(newsize);
}
}